package com.zbkj.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.mybatisflex.core.BaseMapper;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.row.Db;
import com.mybatisflex.core.util.ClassUtil;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.zbkj.admin.boot.redisson.command.Redis;
import com.zbkj.admin.boot.redisson.common.RModule;
import com.zbkj.admin.boot.redisson.common.RedisNameResolver;
import com.zbkj.admin.mapper1.EbOrderProductVoucherRecordMapper;
import com.zbkj.admin.mapper1.EbUserMapper;
import com.zbkj.admin.model.merchant.Merchant;
import com.zbkj.admin.model.order.Order;
import com.zbkj.admin.model.user.User;
import com.zbkj.admin.pojo.*;
import com.zbkj.admin.service.*;
import com.zbkj.admin.util.SecurityUtil;
import com.zbkj.admin.mapper1.EbShopFlowingWaterMapper;
import com.zbkj.admin.model.admin.SystemAdmin;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.result.R;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 店铺营业额度(24小时一条)
 */
@Slf4j
@Service
@SuppressWarnings("all")
@RequiredArgsConstructor
public class EbShopFlowingWaterServiceImpl extends ServiceImpl<EbShopFlowingWaterMapper, EbShopFlowingWaterEntity>
        implements EbShopFlowingWaterService {

//    private static final Integer SPLIT_SIZE = 300;

//    private final ShopScheduled shopScheduled;

    private final Redis redis;
    private final UserService userService;
    private final EbUserMapper ebUserMapper;
    private final OrderService orderService;
    private final ProductService productService;
    private final MerchantService merchantService;
    private final RedisNameResolver redisNameResolver;
    private final OrderDetailService orderDetailService;
    private final SeckillProductService seckillProductService;
    private final EbDividendRecordService dividendRecordService;
    private final EbDividendConfigService dividendConfigService;
    private final EbUserVoucherRecordService userVoucherRecordService;
    private final EbOrderProductVoucherRecordMapper orderVoucherRecordMapper;
    private final IEbUserIntegralProductRecordService integralProductRecordService;

    /**
     * 店铺分红
     *
     * @return 是否分红成功
     */
    @Override
    @Transactional(
            rollbackFor = Exception.class,
            isolation = Isolation.REPEATABLE_READ  // 保证事务内数据可见性
    )
    public R<Boolean> dividend(boolean isLimitationShop, LocalDateTime startData, LocalDateTime endData) {
        LocalDateTime date = LocalDateTime.now(), startTime = date.minusDays(1);
        SystemAdmin admin = SecurityUtil.getLoginUserVo().getUser();
        if (ObjUtil.isEmpty(admin)) {
            return R.fail("请先登录，后操作");
        }
        QueryWrapper where = QueryWrapper.create().from(EbShopFlowingWaterEntity.class).where(EbShopFlowingWaterEntity::getMerId).eq(admin.getMerId());
        // 店铺流水
        List<EbShopFlowingWaterEntity> shopFlowingWaterList = list(where.orderBy(EbShopFlowingWaterEntity::getCreatedTime).desc().limit(2));
        if (ObjUtil.isEmpty(shopFlowingWaterList) && isLimitationShop) {
            return R.fail("店铺流水数据为空");
        }
        // 店铺活动天数
//        long shopFlowingWaterCount = count(where);
        Dict orderPriceList = new Dict(countFlowingWater(startData, endData));
        if (ObjUtil.isEmpty(orderPriceList)) {
            return R.fail("订单价格数据为空");
        }
//        List<Order> userIdList = orderPriceL  ist.getBean("orderList");
//        if (ObjUtil.isEmpty(userIdList)) {
//            return R.fail("用户订单数据为空");
//        }
        QueryWrapper queryWrapper = dividendRecordService.from(EbDividendRecordEntity.class).where(EbDividendRecordEntity::getMerId).eq(admin.getMerId()).eq(EbDividendRecordEntity::getReleaseState, 0);

        EbDividendRecordEntity ebDividendRecord = dividendRecordService.getOne(queryWrapper.clone()
                .orderBy(EbDividendRecordEntity::getCreatedTime).desc().limit(1));

        EbDividendRecordEntity ebDividendRecordEntity = new EbDividendRecordEntity()
                .setCreatedTime(date).setMerId(admin.getMerId()).setCreatedBy("admin").setReleaseState(0);

        AtomicReference<BigDecimal> countPriceInfo = new AtomicReference<>(BigDecimal.ZERO), dividendPrice = new AtomicReference<>(BigDecimal.ZERO), consumerCouponPrice = new AtomicReference<>(BigDecimal.ZERO);

        MapBuilder<String, Object> builder = MapUtil.builder();

        // 首期
        if (Objects.isNull(ebDividendRecord)) {
            Map<String, Object> longDoubleMap = countFlowingWater(startData, endData);
            Map<Long, BigDecimal> map = (Map<Long, BigDecimal>) longDoubleMap.get("ids");
            List<Long> dataIds = (List<Long>) longDoubleMap.get("dataIds");
            handleDate(map, longDoubleMap, ebDividendRecordEntity, 1,
                    1, false, true);
            ebDividendRecordEntity.setExpand(dataIds).setNumOfPeriods(1);
        }
        // 第二期之后
        if (Objects.nonNull(ebDividendRecord)) {

//            AtomicReference<Map<String, BigDecimal>> amount = new AtomicReference<>(new HashMap<>());
//            long between = DateUtil.between(DateUtil.date(ebDividendRecord.getCreatedTime()), DateUtil.date(date),
//                    DateUnit.HOUR, true);

//        if (between < 24L) {
//            return R.fail("释放周期需间隔一天");
//        }
            // 新增：36期扣除逻辑
            if (ebDividendRecord.getRecordTimes() == 36) {
                try {
                    // 执行5倍扣除
                    deductUserPoints(ebDividendRecord.getExpand(), ebDividendRecord.getCycle(), ebDividendRecord.getId());
                } catch (Exception e) {
                    log.error("36期积分扣除失败", e);
                    throw new RuntimeException("积分扣除操作失败");
                }
                // 周期性释放期数+1(开启新一轮36期)
                ebDividendRecordEntity.setCycle(ebDividendRecord.getCycle() + 1)
                        .setNumOfPeriods(1).setRecordTimes(1).setCreatedTime(date).setId(null);
                dividendRecordService.save(ebDividendRecordEntity);

                return R.success(true);
            }
            List<EbDividendRecordEntity> resultList = dividendRecordService.list(dividendRecordService.from(EbDividendRecordEntity.class)
                    .where(EbDividendRecordEntity::getMerId).eq(admin.getMerId())
                    .eq(EbDividendRecordEntity::getReleaseState, 0));

            List<Long> releaseInfos = new ArrayList<>();
            // 往期发放列表
            List<Long> finalReleaseInfos = releaseInfos;
            List<EbDividendRecordEntity> resultListNew = new ArrayList<>();
            resultList.forEach(item -> {
                if (item.getRecordTimes() < 37) {
                    Map<String, Object> longDoubleMap = countFlowingWater(null, null, item.getExpand());
                    Map<Long, BigDecimal> map = (Map<Long, BigDecimal>) longDoubleMap.get("ids");
                    finalReleaseInfos.addAll(item.getExpand());
                    handleDate(map, longDoubleMap, item, item.getRecordTimes() + 1, item.getNumOfPeriods(), true, false);
                    resultListNew.add(item);
                }
            });
            if (CollUtil.isNotEmpty(resultListNew)) {
                dividendRecordService.updateBatch(resultListNew);
            }
            if (ebDividendRecordEntity.getRecordTimes() < 37) {
                releaseInfos = finalReleaseInfos.stream().distinct().collect(Collectors.toList());
                List<Long> finalReleaseInfos1 = releaseInfos;
                Map<String, Object> longDoubleMap = countFlowingWater(startData, endData, it ->
                        !finalReleaseInfos1.contains(it.getId()));
                List<Long> dataIds = (List<Long>) longDoubleMap.get("dataIds");
                Map<Long, BigDecimal> map = (Map<Long, BigDecimal>) longDoubleMap.get("ids");
                handleDate(map, longDoubleMap, ebDividendRecordEntity, 1,
                        ebDividendRecord.getNumOfPeriods() + 1, false, true);
                ebDividendRecordEntity.setExpand(dataIds);

                // 设置继承关系
                ebDividendRecordEntity.setNumOfPeriods(ebDividendRecord.getNumOfPeriods() + 1);
            } else {
                String format = StrUtil.format("释放第{}期36笔结束", ebDividendRecord.getNumOfPeriods());
                return R.fail(format);
            }

        }

        if (ebDividendRecordEntity.getDividendPrice().doubleValue() > 0) {
            dividendRecordService.save(ebDividendRecordEntity);

            ebDividendRecordEntity.getExpand().forEach(it -> {
                EbOrderProductVoucherRecordEntity ebOrderProductVoucherRecordEntity = orderVoucherRecordMapper.selectOneById(it);
                ebOrderProductVoucherRecordEntity.setIsEffective(1);
                orderVoucherRecordMapper.update(ebOrderProductVoucherRecordEntity);
            });
        } else {
            log.warn("没有新的订单无法释放 {} 期", ebDividendRecordEntity.getNumOfPeriods());
        }
        return R.success(true);
    }

    /**
     * 释放用户36期积分
     *
     * @param firstPeriodData 上一期释放数据
     * @param multiplier      扣除倍数
     */
    private void deductUserPoints(List<Long> expand, Long multiplier, Long id) {
        expand.forEach(it -> {
            EbOrderProductVoucherRecordEntity ebOrderProductVoucherRecordEntity = orderVoucherRecordMapper.selectOneById(it);
            EbUserIntegralProductRecordEntity recordServiceOne = integralProductRecordService.getOne(integralProductRecordService.from().where(EbUserIntegralProductRecordEntity::getUid)
                    .eq(ebOrderProductVoucherRecordEntity.getUid()));
            BigDecimal count = BigDecimal.ZERO;
            ebOrderProductVoucherRecordEntity.getData().entrySet().forEach(item -> {
                count.add((BigDecimal) item.getValue());
            });
            String format = StrUtil.format("已完成36释放扣除{}积分", count);
            integralProductRecordService.save(EbUserIntegralProductRecordEntity.builder().uid(Math.toIntExact(ebOrderProductVoucherRecordEntity.getUid()))
                    .balance(recordServiceOne.getBalance().subtract(count)).linkType("order").linkId(ebOrderProductVoucherRecordEntity.getOrderNo())
                    .integral(count).mark(format).type(2).build());
        });
        // 删除释放记录
        if (Objects.nonNull(id)) {
            dividendRecordService.removeById(id);
        }
//        List<EbUserVoucherRecordEntity> deductions = new ArrayList<>();
//
//        firstPeriodData.forEach((userIdStr, releaseInfo) -> {
//            Long userId = Long.parseLong(userIdStr);
//            releaseInfo.getSummaryProductInfo().forEach(productMap -> {
//                productMap.forEach((productId, points) -> {
//                    BigDecimal originalPoints = (BigDecimal) points;
//                    BigDecimal deduction = originalPoints.multiply(BigDecimal.valueOf(multiplier));
//
//                    deductions.add(new EbUserVoucherRecordEntity().setUid(userId.intValue()).setVoucher(deduction).setType(2) // 2表示扣除类型
//                            .setMark("冻结积分扣除").setCreateTime(LocalDateTime.now()));
//                });
//            });
//        });
//
//        if (!deductions.isEmpty()) {
//            userVoucherRecordService.saveBatch(deductions);
//        }
    }

    /**
     * 计算分红额度
     *
     * @param proportion   增长比例
     * @param targetPeriod 分期期数
     * @param initPrice    首期初始金额
     * @param maxPeriod    最大计算期数
     */
    @Override
    public Dict priceCount(long proportion, int targetPeriod, BigDecimal initPrice, Long maxPeriod) {
        RoundingMode unit = RoundingMode.DOWN;
        if (targetPeriod >= 1) {
            final double INIT_POOL = initPrice.doubleValue();     // 初始分红池
            final BigDecimal GROWTH_RATE = new BigDecimal(proportion);    // 每期增幅15%
            final BigDecimal prop = GROWTH_RATE.add(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(100), 2, unit);
            // 比例一半
            final BigDecimal[] halfProp = {new BigDecimal("0.005")};
            final int TARGET_PERIOD = targetPeriod + 1;       // 目标期数
            // 大于36期停止
            if (TARGET_PERIOD > maxPeriod + 1) {
                return Dict.of().set("countPrice", BigDecimal.ZERO).set("dividendPrice", BigDecimal.ZERO).set("consumerCouponPrice", BigDecimal.ZERO).set("numOfPeriods", targetPeriod);
            }

            AtomicReference<BigDecimal> pool = new AtomicReference<>(new BigDecimal(INIT_POOL)), total = new AtomicReference<>(initPrice), count = new AtomicReference<>(initPrice.divide(BigDecimal.valueOf(100), 2, unit));
            if (targetPeriod == 1) {
                pool.updateAndGet(v -> initPrice.multiply(halfProp[0]).setScale(2, unit));
                count.updateAndGet(v -> pool.get().multiply(new BigDecimal("2")));
                return Dict.of().set("countPrice", count.get()).set("dividendPrice", total.get()).set("consumerCouponPrice", pool.get()).set("numOfPeriods", targetPeriod);
            }
            // 生成表格内容
            IntStream.rangeClosed(1, TARGET_PERIOD).forEach(period -> {
                // 更新池和累计值（最后一期不增长）
                if (period < TARGET_PERIOD && period > 1) {
                    if (period == 36) {
                        halfProp[0] = new BigDecimal("0.004468");
                    } else {
                        halfProp[0] = new BigDecimal("0.005");
                    }
                    pool.updateAndGet(v -> initPrice.multiply(prop.pow(period - 1)).multiply(halfProp[0]).setScale(2, unit));
                    total.updateAndGet(v -> initPrice.multiply(prop.pow(period - 1)).setScale(2, unit));
                    count.updateAndGet(v -> v.add(pool.get().multiply(BigDecimal.valueOf(2))));
                    log.info("第{}期：{} 分红池 {} 两人消费券 {} 累计汇总 {}", period, pool.get(), total.get(), pool.get().multiply(BigDecimal.valueOf(2)), count.get());
                }
            });
            // countPrice 累计分红(金额)
            // dividendPrice 分红池(金额)
            return Dict.of().set("countPrice", count.get()).set("dividendPrice", total.get()).set("consumerCouponPrice", pool.get()).set("numOfPeriods", targetPeriod);
        }
        return Dict.of().set("countPrice", BigDecimal.ZERO).set("dividendPrice", BigDecimal.ZERO).set("consumerCouponPrice", BigDecimal.ZERO).set("numOfPeriods", targetPeriod);
    }

    /**
     * 计算指定期数分红
     *
     * @param period                 期数
     * @param recordTimes            （期数）的记录那一笔(第1期第2笔)
     * @param isDividend             是否分红(在for循环下为true)正常情况为false
     * @param cycle                  是否循环(在for循环下为false)正常情况为true
     * @param ebDividendRecordEntity 分红原始记录
     * @param data                   订单商品积分数据 (key:商品id value:商品积分)
     */
    @Override
    public void handleDate(Map<Long, BigDecimal> data, Map<String, Object> longDoubleMap, EbDividendRecordEntity ebDividendRecordEntity,
                           Integer recordTimes, Integer period, Boolean isDividend, Boolean cycle) {
        if (isDividend) {
            ebDividendRecordEntity.setRecordTimes(ebDividendRecordEntity.getRecordTimes() + 1);
        }
        Map<Long, List<EbOrderProductVoucherRecordEntity>> orderdata = (Map<Long, List<EbOrderProductVoucherRecordEntity>>) longDoubleMap.get("userOrder");
        AtomicInteger userPoints = new AtomicInteger(1);
        AtomicReference<BigDecimal> dividendPrice = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> counterPrice = new AtomicReference<>(BigDecimal.ZERO);
        AtomicReference<BigDecimal> consumerCouponPrice = new AtomicReference<>(BigDecimal.ZERO);
        List<EbUserVoucherRecordEntity> voucherRecord = new ArrayList<>();
        List<EbUserEntity> userList = new ArrayList<>();
        if (Objects.nonNull(data)) {
            data.forEach((uid, points) -> {
                Integer userPointses = 1;
                if (!cycle) {
                    userPointses = isDividend ? ebDividendRecordEntity.getRecordTimes() : period;
                }
                User user = userService.getById(uid);
                if (Objects.isNull(user.getVoucher())) {
                    user.setVoucher(BigDecimal.ZERO);
                }
                Dict dict = priceCount(15, userPointses, points, 36L);
                BigDecimal consumerCouponPricei = dict.getBigDecimal("consumerCouponPrice");
                BigDecimal dividendPriceInfo = dict.getBigDecimal("dividendPrice");
                BigDecimal countPrice = dict.getBigDecimal("countPrice");
                dividendPrice.updateAndGet(v -> v.add(dividendPriceInfo));
                counterPrice.updateAndGet(v -> v.add(countPrice));
                consumerCouponPrice.updateAndGet(v -> v.add(consumerCouponPricei));
                if (Objects.nonNull(user)) {
                    EbUserVoucherRecordEntity recordEntity = userVoucherRecordService.getOne(userVoucherRecordService
                            .from().where(EbUserVoucherRecordEntity::getUid).eq(uid)
                            .orderBy(EbUserVoucherRecordEntity::getCreateTime).desc().limit(1));

                    List<EbOrderProductVoucherRecordEntity> recordEntities = orderdata.get(uid);
                    String order = recordEntities.stream().parallel().map(EbOrderProductVoucherRecordEntity::getOrderNo).collect(Collectors.joining(","));
                    String format = StrUtil.format("订单{}抵用券释放第{}笔，释放", order, recordTimes);
                    log.debug(format);
                    BigDecimal balance = Objects.nonNull(recordEntity) ?
                            user.getVoucher().add(consumerCouponPricei) : BigDecimal.ZERO.add(consumerCouponPricei);
                    EbUserVoucherRecordEntity voucherRecordEntity = EbUserVoucherRecordEntity.builder().mark(format)
                            .uid(Math.toIntExact(uid)).linkType("order")
                            .linkId(order + ":" + period).type(1).title("").voucher(consumerCouponPricei).status(5)
                            .createTime(LocalDateTime.now().plusSeconds(userPoints.incrementAndGet()))
                            .balance(balance).updateTime(LocalDateTime.now()).build();
                    voucherRecord.add(voucherRecordEntity);
                    userList.add(EbUserEntity.builder().id(Math.toIntExact(uid)).voucher(balance).build());
                    userService.lambdaUpdate().set(User::getVoucher, balance).eq(User::getId, uid).update();
                }
            });
            if (!isDividend) {
                ebDividendRecordEntity.setRecordTimes(recordTimes).setNumOfPeriods(period)
                        .setAmount(dividendPrice.get()).setDividendPrice(dividendPrice.get())
                        .setCountPrice(counterPrice.get()).setConsumerCouponPrice(consumerCouponPrice.get());
            }
        }
        userVoucherRecordService.saveBatch(voucherRecord);
//        ebUserMapper.updateBatch(userList);
//        Db.executeBatch(userList, 1000, ClassUtil.getUsefulClass(ebUserMapper.getClass()), BaseMapper::insertOrUpdateSelective);
    }

    /**
     * 数据分页
     *
     * @param page      分页信息
     * @param shopName  店铺名称
     * @param state     分红状态
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return 分页数据
     */
    @Override
    public R<PageInfo<EbDividendRecordEntity>> page(Page<EbDividendRecordEntity> page, String shopName, Integer state, LocalDateTime startDate, LocalDateTime endDate) {
        Integer merId;
        if (StrUtil.isBlank(shopName)) {
            SystemAdmin admin = SecurityUtil.getLoginUserVo().getUser();
            merId = admin.getMerId();
        } else {
            Merchant one = merchantService.getOne(Wrappers.<Merchant>lambdaQuery().eq(Merchant::getName, shopName));
            if (ObjUtil.isEmpty(one)) {
                return R.fail("此商户不存在");
            }
            merId = one.getId();
        }

        // 店铺流水
        QueryWrapper where = QueryWrapper.create().from(EbDividendRecordEntity.class).where(EbDividendRecordEntity::getMerId).eq(merId);
        EbDividendRecordEntity ebDividendRecord = dividendRecordService.getOne(where.orderBy(EbDividendRecordEntity::getCreatedTime).desc().limit(1));

        EbDividendConfigEntity dividendConfig = dividendConfigService.getOne(QueryWrapper.create().from(EbDividendConfigEntity.class).where(EbDividendConfigEntity::getMerId).eq(merId).orderBy(EbDividendConfigEntity::getCreatedTime).desc().limit(1));

//        BigDecimal increasePrice = ebDividendRecord.getCountPrice().divide(dividendConfig.getProportion().divide(BigDecimal.valueOf(100L), 2, RoundingMode.HALF_UP)
//                , 2, RoundingMode.HALF_UP);

        Integer finalMerId = merId;
        LocalDateTime finalStartDate = startDate;
        LocalDateTime finalEndDate = endDate;
        PageInfo<EbDividendRecordEntity> objectPageInfo = PageHelper.startPage(page.getPageNum(), page.getPageSize()).doSelectPageInfo(() -> dividendRecordService.list(QueryWrapper.create().from(EbDividendRecordEntity.class).eq(EbDividendRecordEntity::getMerId, finalMerId, ObjUtil::isNotEmpty).eq(EbDividendRecordEntity::getReleaseState, state, ObjUtil::isNotEmpty).gt(EbDividendRecordEntity::getCreatedTime, finalStartDate, ObjUtil::isNotEmpty).lt(EbDividendRecordEntity::getCreatedTime, finalEndDate, ObjUtil::isNotEmpty)
//                        .eq(EbDividendRecordEntity::getReleaseState, 1)
                .orderBy(EbDividendRecordEntity::getNumOfPeriods).desc()));

        startDate = startDate == null ? LocalDateTime.now() : startDate;
        endDate = endDate == null ? LocalDateTime.now() : endDate;
        long startDateTime = DateUtil.beginOfDay(DateUtil.date(startDate)).getTime(), endDateTime = DateUtil.endOfDay(DateUtil.date(endDate.withHour(23).withMinute(59).withSecond(59))).getTime();

        BigDecimal todayCountOrderPrice = orderService.countOrderPrice(startDateTime, endDateTime, Long.valueOf(merId));
        todayCountOrderPrice = todayCountOrderPrice == null ? BigDecimal.ZERO : todayCountOrderPrice;

//        boolean isDividend;
//        if (todayCountOrderPrice.compareTo(increasePrice) > 0) {
//            isDividend = true;
//        } else {
//            isDividend = false;
//        }
        List<EbDividendRecordEntity> data = objectPageInfo.getList();
        data.forEach(item -> {
//            item.setIsDividend(isDividend);
            if (item.getReleaseState() == 0) {
                item.setPercentage(BigDecimal.valueOf(100L));
            } else {
                EbShopFlowingWaterEntity one = getOne(QueryWrapper.create().from(EbShopFlowingWaterEntity.class).eq(EbShopFlowingWaterEntity::getMerId, item.getMerId()).le(EbShopFlowingWaterEntity::getCreatedTime, item.getCreatedTime().minusDays(1)).limit(1));
                EbShopFlowingWaterEntity toDay = getOne(QueryWrapper.create().from(EbShopFlowingWaterEntity.class).eq(EbShopFlowingWaterEntity::getMerId, item.getMerId()).le(EbShopFlowingWaterEntity::getCreatedTime, item.getCreatedTime()).limit(1));
                // 进度条计算
                if (ObjUtil.isNotEmpty(one) && ObjUtil.isNotEmpty(toDay)) {
                    BigDecimal multiply = one.getBusinessLimit().multiply(BigDecimal.valueOf(15).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
                    BigDecimal add = one.getBusinessLimit().add(multiply);
                    BigDecimal divide = toDay.getBusinessLimit().divide(add, 2, RoundingMode.HALF_UP);
                    item.setPercentage(divide);
                } else {
                    item.setPercentage(BigDecimal.ZERO);
                }

            }
        });
        objectPageInfo.setList(data);
        return R.success(objectPageInfo);
    }

    /**
     * 统计数据
     *
     * @param isToday   是否统计今日数据
     * @param uidList   用户id集合
     * @param predicate 条件
     * @return 数据
     */
    @Override
    public Map<String, Object> countFlowingWater(Boolean isToday, LocalDateTime startTme, LocalDateTime end,
                                                 List<Long> uidList, Predicate<EbOrderProductVoucherRecordEntity> predicate) {
//        Map<String, Object> redisData = redis.get(redisNameResolver.resolve(RModule.LCache, "shopcountFlowingWater"));
//        if (MapUtil.isNotEmpty(redisData)) {
//            return redisData;
//        }
        Map<String, Object> data = new HashMap<>();
        List<Long> dataIds = new ArrayList<>();
        List<EbOrderProductVoucherRecordEntity> recordEntities = new ArrayList<>();
        LocalDateTime date = isToday ? LocalDateTime.now() : null,
                startTime = isToday ? DateUtil.toLocalDateTime(DateUtil.beginOfDay(DateUtil.date(date))) : null;

        startTime = Objects.isNull(startTme) ? startTme : startTme;
        date = Objects.isNull(end) ? date : end;

        QueryWrapper queryWrapper = dividendRecordService.from(EbOrderProductVoucherRecordEntity.class)
                .where(EbOrderProductVoucherRecordEntity::getCreateTime).ge(startTime)
                .le(EbOrderProductVoucherRecordEntity::getCreateTime, date);
        if (CollUtil.isNotEmpty(uidList)) {
            List<List<Long>> partition = Lists.partition(uidList, 300);
            partition.forEach(ids -> {
                recordEntities.addAll(orderVoucherRecordMapper.selectListByQuery(queryWrapper
                        .in(EbOrderProductVoucherRecordEntity::getId, ids, !isToday)));
            });
        } else {
            recordEntities.addAll(orderVoucherRecordMapper.selectListByQuery(queryWrapper));
        }

        Predicate<EbOrderProductVoucherRecordEntity> falsePredicate = it -> true;
        // 获取用户总积分
        Map<Long, Double> collect = recordEntities.stream()
                .filter(Optional.ofNullable(predicate).orElse(falsePredicate))
                .peek(it -> dataIds.add(it.getId()))
                .parallel().collect(Collectors.groupingBy(EbOrderProductVoucherRecordEntity::getUid,
                        Collectors.summingDouble(it ->
                                it.getData().values().parallelStream().map(String::valueOf).map(BigDecimal::new)
                                        .mapToDouble(BigDecimal::doubleValue).reduce(0D, Double::sum))));

        Map<Long, List<EbOrderProductVoucherRecordEntity>> longListMap = recordEntities.stream()
                .filter(Optional.ofNullable(predicate).orElse(falsePredicate))
                .collect(Collectors.groupingBy(EbOrderProductVoucherRecordEntity::getUid));

        // 转换类型
        Map<Long, BigDecimal> result = new HashMap<>();
        collect.entrySet().stream().peek(it -> result.put(it.getKey(), BigDecimal.valueOf(it.getValue())))
                .parallel().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        Map<String, Object> objectMap = MapUtil.builder(data).put("ids", result).put("data", collect).put("dataIds", dataIds)
                .put("userOrder", longListMap)
                .put("orderNoList", recordEntities.stream().map(EbOrderProductVoucherRecordEntity::getOrderNo).collect(Collectors.toList())).build();
//        redis.setEx(redisNameResolver.resolve(RModule.LCache, "shopcountFlowingWater"), objectMap, Duration.ofSeconds(1));
//        redis.setEx(redisNameResolver.resolve(RModule.LCache, "orderProduct"), recordEntities, Duration.ofSeconds(1));
        return objectMap;
    }

}
